/// \file
/// \author Martin Dubcovsky
/// This file defines a view frustrum that holds references to a camera's
/// view and projection matrix. Thus when Update is called, the frustrum is
/// recalculated based on the state of those 2 matrices at the time the 
/// call to update is made.
/// \remarks Update does a matrix inversion which can be a bit costly, so
/// the calling code should check if the frustrum really needs to be updated

#ifndef GRAPHICS_VIEW_FRUSTRUM_H
#define GRAPHICS_VIEW_FRUSTRUM_H

#include "boost/array.hpp"
#include "boost/scoped_array.hpp"

#include "graphics/basic.h"
#include "graphics/frustrum.h"

namespace graphics{
    
class ViewFrustrum : public Frustrum{
public:
    ViewFrustrum(Matrix & view, Matrix & projection);
    ViewFrustrum(Matrix & inverse_view_projection);

    //int Update() {
    //    math::Matrix temp = view_ * projection_;
    //    temp.inverse();

    //    corners_[xyz_CORNER].point_ = cml::transform_point(temp, Point(-1.0f, -1.0f, 0.0f)); // xyz
    //    corners_[Xyz_CORNER].point_ = cml::transform_point(temp, Point(1.0f, -1.0f, 0.0f));  // Xyz
    //    corners_[xYz_CORNER].point_ = cml::transform_point(temp, Point(-1.0f, 1.0f, 0.0f));  // xYz
    //    corners_[XYz_CORNER].point_ = cml::transform_point(temp, Point(1.0f, 1.0f, 0.0f));   // XYz
    //    corners_[xyZ_CORNER].point_ = cml::transform_point(temp, Point(-1.0f, -1.0f, 1.0f)); // xyZ
    //    corners_[XyZ_CORNER].point_ = cml::transform_point(temp, Point(1.0f, -1.0f, 1.0f));  // XyZ
    //    corners_[xYZ_CORNER].point_ = cml::transform_point(temp, Point(-1.0f, 1.0f, 1.0f));  // xYZ
    //    corners_[XYZ_CORNER].point_ = cml::transform_point(temp, Point(1.0f, 1.0f, 1.0f));   // XYZ


    //    Normal normal;  //use as a temp place to compute each face's normal

    //    //TOP_FACE == Plane(xYz, XYz - xYz, xYZ - xYz)
    //    plane_list_[TOP_FACE] = math::Plane::FromPoints(&corners_[xYz_CORNER], &corners_[XYz_CORNER], &corners_[xYZ_CORNER]);
    //    normal = plane_list_[TOP_FACE].GetNormal();
    //    if(cml::dot(corners_[xyz_CORNER].point_, normal) < 0)
    //        plane_list_[TOP_FACE].SetNormal(-normal);
    //    
    //    //BOTTOM_FACE == Plane(xyz, xyZ - xyz, Xyz - xyz)
    //    plane_list_[BOTTOM_FACE] = math::Plane::FromPoints(&corners_[xyz_CORNER], &corners_[xyZ_CORNER], &corners_[Xyz_CORNER]);
    //    normal = plane_list_[BOTTOM_FACE].GetNormal();
    //    if(cml::dot(corners_[xYz_CORNER].point_, normal) < 0)
    //        plane_list_[BOTTOM_FACE].SetNormal(-normal);     

    //    //RIGHT_FACE == Plane(Xyz, XyZ, XYz)
    //    plane_list_[RIGHT_FACE] = math::Plane::FromPoints(&corners_[Xyz_CORNER], &corners_[XyZ_CORNER], &corners_[XYz_CORNER]);
    //    normal = plane_list_[RIGHT_FACE].GetNormal();
    //    if( cml::dot(corners_[xyz_CORNER].point_, normal) < 0)
    //        plane_list_[RIGHT_FACE].SetNormal(-normal);           
    //    
    //    
    //    //LEFT_FACE == Plane(xyz, xYz, xyZ)
    //    plane_list_[LEFT_FACE] = math::Plane::FromPoints(&corners_[xyz_CORNER], &corners_[xYz_CORNER], &corners_[xyZ_CORNER]);
    //    normal = plane_list_[LEFT_FACE].GetNormal();
    //    if( cml::dot(corners_[Xyz_CORNER].point_, normal) < 0)
    //        plane_list_[LEFT_FACE].SetNormal(-normal);     

    //    
    //    //BACK_FACE == Plane(xyZ, xYZ, XyZ)
    //    plane_list_[BACK_FACE] = math::Plane::FromPoints(&corners_[xyZ_CORNER], &corners_[xYZ_CORNER], &corners_[XyZ_CORNER]);
    //    normal = plane_list_[BACK_FACE].GetNormal();
    //    if( cml::dot(corners_[xyz_CORNER].point_, normal) < 0)
    //        plane_list_[BACK_FACE].SetNormal(-normal);     


    //    //FRONT_FACE == Plane(xyz, Xyz, xYz)
    //    plane_list_[FRONT_FACE] = math::Plane::FromPoints(&corners_[xyz_CORNER], &corners_[Xyz_CORNER], &corners_[xYz_CORNER]);
    //    normal = plane_list_[FRONT_FACE].GetNormal();
    //    if( cml::dot(corners_[xyZ_CORNER].point_, normal) < 0)
    //        plane_list_[FRONT_FACE].SetNormal(-normal);            
    //    
    //}

    
};

} //namespace graphics
#endif // GRAPHICS_VIEW_FRUSTRUM_H